package org.gary.base.dao.impl;

import java.sql.SQLException;
import java.util.List;
import javax.annotation.Resource;

import lengreen.core.interfaces.Entity;

import org.gary.base.dao.CategoryDao;
import org.gary.base.model.Category;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

/**
 * category的dao
 * @author lengreen
 * 
 */
@Component("categoryDao")
public class CategoryDaoImpl implements CategoryDao {
	private HibernateTemplate hibernateTemplate;
	private String hql;

	@Override
	public List<Object[]> list(String whoCategory, String lang) {
		setHql("select category.id, category.name from "
				+ Category.class.getName()
				+ " category where category.whoCategory = '" + whoCategory
				+ "' and category.visible = true and category.lang = '" + lang
				+ "'");
		List<Object[]> categorys = hibernateTemplate
				.execute(new HibernateCallback<List<Object[]>>() {

					@SuppressWarnings("unchecked")
					@Override
					public List<Object[]> doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query q = session.createQuery(getHql());
						return q.list();
					}
				});
		return categorys;
	}

	@Override
	public List<Object[]> listParent(String whoCategory, String lang) {
		setHql("select category.id, category.name from "
				+ Category.class.getName()
				+ " category where category.whoCategory = '" + whoCategory
				+ "' and category.visible = true and category.lang = '" + lang
				+ "' and category.parent = null");
		List<Object[]> categorys = hibernateTemplate
				.execute(new HibernateCallback<List<Object[]>>() {

					@SuppressWarnings("unchecked")
					@Override
					public List<Object[]> doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query q = session.createQuery(getHql());
						return q.list();
					}
				});
		return categorys;
	}

	@Override
	public Category loadCategoryByName(String categoryName, String lang) {
		setHql("from " + Category.class.getName()
				+ " category where category.name = '" + categoryName + "'" +
				" and category.lang = '" + lang + "'");
		Category category = hibernateTemplate
				.execute(new HibernateCallback<Category>() {

					@Override
					public Category doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query q = session.createQuery(getHql());
						return (Category) q.uniqueResult();
					}
				});
		return category;
	}

	public int checkNameExist(String name, String lang) {
		setHql("select count(*) from " + Category.class.getName()
				+ " category where category.name = '" + name + "'" +
				" and category.lang = '" + lang + "'");
		Integer count = hibernateTemplate
				.execute(new HibernateCallback<Integer>() {

					@Override
					public Integer doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query q = session.createQuery(getHql());
						return new Integer(q.uniqueResult().toString());
					}
				});
		return count;
	}

	@Override
	public int associateCount(int categoryId, Class<? extends Entity> entity) {
		setHql("select count(*) from " + entity.getName() + " entity where"
				+ " entity.category.id = " + categoryId);
		Object count = hibernateTemplate
				.execute(new HibernateCallback<Object>() {

					@Override
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query q = session.createQuery(getHql());
						return q.uniqueResult();
					}
				});
		return new Integer(count.toString());
	}

	@Override
	public <T> T children(int categoryId) {
		setHql("select category.children from " + Category.class.getName()
				+ " category where category.id = " + categoryId);
		T children = hibernateTemplate.execute(new HibernateCallback<T>() {

			@SuppressWarnings("unchecked")
			@Override
			public T doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query q = session.createQuery(getHql());
				return (T) q.list();
			}
		});
		return children;
	}

	@Resource
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHql(String hql) {
		this.hql = hql;
	}

	public String getHql() {
		return hql;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Category> getList(String whoCategory, Object lang) {
		setHql("from " + Category.class.getName()
				+ " category where visible=true and whoCategory = '"
				+ whoCategory + "' and lang='" + lang + "'");
		List<Category> categorys = hibernateTemplate
				.executeFind(new HibernateCallback<List<Category>>() {

					@Override
					public List<Category> doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query q = session.createQuery(getHql()).setCacheable(
								true);
						return q.list();
					}
				});
		return categorys;
	}

	@Override
	public <T> List<T> loadXxxByCategory(Class<T> entity, int categoryId) {
		setHql("from " + entity.getName()
				+ " entity where entity.category.id = " + categoryId);
		List<T> t = hibernateTemplate.execute(new HibernateCallback<List<T>>() {

			@SuppressWarnings("unchecked")
			public List<T> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query q = session.createQuery(hql);
				return q.list();
			}
		});
		return t;
	}

}
